package com.seeyou.domorutil;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity {


    private HashMap<Integer, DatagramSocket> sockets = new HashMap<>();
    private TextView rec25000msg, rec25000data, rec25001, rec15724;
    private EditText msg25000, msg25001, msg15724, edip;
    private Handler mHandler = new Handler();


    private HandlerThread sendThread;
    private Handler sendHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rec25000msg = findViewById(R.id.rec25000msg);
        rec25000data = findViewById(R.id.rec25000data);
        rec25001 = findViewById(R.id.rec25001);
        rec15724 = findViewById(R.id.rec15724);
        edip = findViewById(R.id.edip);

        msg25000 = findViewById(R.id.content25000);
        msg25001 = findViewById(R.id.content25001);
        msg15724 = findViewById(R.id.content15974);

        startReceive(25000);
        startReceive(25001);
        startReceive(15724);

        sendThread = new HandlerThread("sendThread");
        sendThread.start();
        sendHandler = new Handler(sendThread.getLooper());
    }


    public void broadcast25000(View view) {
        String msg = msg25000.getText().toString();
        if(TextUtils.isEmpty(msg)) msg = "null";
        broadcast(25000, "",25000, msg);
    }

    public void broadcast25001(View view) {
        String msg = msg25001.getText().toString();
        if(TextUtils.isEmpty(msg)) msg = "null";
        broadcast(25000, "",25001, msg);
    }

    public void broadcast15724(View view) {
        String msg = msg15724.getText().toString();
        if(TextUtils.isEmpty(msg)) msg = "null";

        broadcast(25000, edip.getText().toString(),15724, msg);
    }

    public void whoami(View view) {
        broadcast(25000, "",15724, "whoami");
    }

    public void startReceive(final int port) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                DatagramSocket datagramSocket = sockets.get(port);

                if(datagramSocket == null || datagramSocket.isClosed()) {
                    try {
                        datagramSocket = new DatagramSocket(port);
                    } catch (SocketException e) {
                        e.printStackTrace();
                    }
                    sockets.put(port, datagramSocket);
                }

                while(true) {
                    byte[] buf = new byte[1024];
                    DatagramPacket dp = new DatagramPacket(buf, buf.length);
                    try {
                        datagramSocket.receive(dp);
                        final boolean wristband = isWristband(buf);

                        String data = "";
                        if(wristband) {
                            data = initDeviceData(buf);
                        } else {
                            data = new String(buf);
                        }

                        final String fianlData = data;
                        int fromPort = dp.getPort();
                        final String newData = fromPort + ":" + fianlData;
//                        final String newData = fianlData;

                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                switch (port) {
                                    case 25000:
                                        if(wristband) {
                                            String content = rec25000data.getText().toString() + "\n" + newData;
                                            if (content.length() > 10000)  content = newData;
                                            rec25000data.setText(content);
                                        } else {
                                            String content1 = rec25000msg.getText().toString() + "\n"+ newData;
                                            if (content1.length() > 10000)  content1 = newData;
                                            rec25000msg.setText(content1);
                                        }

                                        break;
                                    case 25001:
                                        String content2 = rec25001.getText().toString() + "\n"+ newData;
                                        if (content2.length() > 10000)  content2 = newData;
                                        rec25001.setText(content2);
                                        break;
                                    case 15724:
                                        String content3 = rec15724.getText().toString() + "\n"+ newData;
                                        if (content3.length() > 10000)  content3 = newData;
                                        rec15724.setText(content3);
                                        break;
                                }
                            }
                        });

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }


    private boolean isWristband(byte[] src) {
        return (src[0] & 0xFF) == 221;
    }

    private String initDeviceData(byte[] buffer){
        final int no = (buffer[1]  << 16) + (buffer[2] << 18)  + buffer[3];
        final String sNo = addZeroForNum(Integer.toHexString(no), 6);
//        final String sNo = addZeroForNum("1", 6);
        final int data = (buffer[4] & 0xFF);
        return ":" + sNo + ":" + data;
    }

    public String addZeroForNum(String str, int strLength) {
        int strLen = str.length();
        if (strLen < strLength) {
            while (strLen < strLength) {
                StringBuffer sb = new StringBuffer();
                sb.append("0").append(str);// 左补0
                // sb.append(str).append("0");//右补0
                str = sb.toString();
                strLen = str.length();
            }
        }

        return str;
    }


    public void broadcast(final int localPort, final String ip, final int targetPort, final String msg) {
        sendHandler.post(new Runnable() {
            @Override
            public void run() {

                DatagramSocket datagramSocket = sockets.get(localPort);
                if(datagramSocket == null) {
                    try {
                        datagramSocket = new DatagramSocket(localPort);
                    } catch (SocketException e) {
                        e.printStackTrace();
                    }
                    sockets.put(localPort, datagramSocket);
                }

                byte[]  data = msg.getBytes();

                try {
                    InetAddress hostAddress;
                    if(TextUtils.isEmpty(ip)) {
                        hostAddress = InetAddress.getByName("255.255.255.255");
                    } else {
                        hostAddress = InetAddress.getByName(ip);
                    }
                    DatagramPacket dp = new DatagramPacket(data, data.length, hostAddress, targetPort);
                    datagramSocket.send(dp);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
    }





    @Override
    protected void onDestroy() {
        super.onDestroy();
        Collection<DatagramSocket> values = sockets.values();
        for(DatagramSocket socket : values) {
            socket.close();
        }
    }


}